import { Material, MaterialContent, MaterialContentNewsItem } from '../entities'
import { InjectRepository } from '@nestjs/typeorm'
import { MaterialResponseInterface, MaterialInterface, MeterialType } from '../model'
import { HttpService } from '@nestjs/common'
import { WechatService } from '../../../../services'
import { Observable } from 'rxjs'
import { map, switchMap, catchError } from 'rxjs/operators'
import { Injectable } from '@angular/core'
import { Repository, DeepPartial } from 'typeorm'

@Injectable()
export class MaterialService {
  get listUrl(): Observable<string> {
    return this.wechat.accessToken.pipe(
      map(access_token => {
        return `https://api.weixin.qq.com/cgi-bin/material/batchget_material?access_token=${access_token}`
      })
    )
  }
  constructor(
    private wechat: WechatService,
    private http: HttpService,
    @InjectRepository(Material) public material: Repository<Material>,
    @InjectRepository(MaterialContent) public materialContent: Repository<MaterialContent>,
    @InjectRepository(MaterialContentNewsItem)
    public materialContentItem: Repository<MaterialContentNewsItem>
  ) {
    this.wechat.init('wx6e41c8b66a4a3cf1', '8ae449cecb0e1bc9d704337f397ab06a')
  }

  async getMaterialList() {
    return await this.material.find({})
  }

  getList(
    type: 'image' | 'video' | 'voice' | 'news',
    offset: number = 0,
    count: number = 20
  ): Promise<MaterialResponseInterface> {
    return new Promise((resolve, reject) => {
      this.listUrl
        .pipe(
          switchMap((listUrl: string) => {
            return this.http.post(listUrl, {
              type: type,
              offset: offset,
              count: count
            })
          }),
          map(res => res.data)
        )
        .subscribe(
          res => {
            resolve(res)
          },
          err => {
            reject(err)
          },
          () => {}
        )
    })
  }

  async createMaterial(media: MaterialInterface, type: MeterialType) {
    const material = new Material()
    material.media_id = media.media_id
    material.name = media.name
    material.update_time = media.update_time
    material.url = media.url
    material.media_type = type
    const materialContent = media.content
    if (materialContent) {
      const content = new MaterialContent()
      content.create_time = materialContent.create_time
      content.update_time = materialContent.update_time
      // 插入item
      const news_item = materialContent.news_item
      content.news_item = content.news_item || []
      for (let key in news_item) {
        const item = news_item[key]
        const contentItem = new MaterialContentNewsItem()
        contentItem.author = item.author
        contentItem.content = item.content
        contentItem.content_source_url = item.content_source_url
        contentItem.digest = item.digest
        contentItem.need_open_comment = item.need_open_comment === 1
        contentItem.only_fans_can_comment = item.only_fans_can_comment === 1
        contentItem.show_cover_pic = item.show_cover_pic === 1
        contentItem.thumb_media_id = item.thumb_media_id
        contentItem.thumb_url = item.thumb_url
        contentItem.title = item.title
        contentItem.url = item.url
        content.news_item.push(contentItem)
      }
      material.content = content
      await this.material.insert(material)
      content.material = material
      await this.materialContent.insert(content)
      for (let key in content.news_item) {
        const item = content.news_item[key]
        item.materialContent = content
        this.materialContentItem.insert(content.news_item[key]).then(res => {
          console.log(res)
        })
      }
    } else {
      await this.material.insert(material)
    }
    return material
  }

  async initList() {
    const images: MaterialResponseInterface = await this.getList('image')
    const videos: MaterialResponseInterface = await this.getList('video')
    const voices: MaterialResponseInterface = await this.getList('voice')
    const news: MaterialResponseInterface = await this.getList('news')

    for (let key in images.item) {
      const mat = images.item[key]
      await this.createMaterial(mat, 'image')
    }

    for (let key in videos.item) {
      const mat = videos.item[key]
      await this.createMaterial(mat, 'video')
    }

    for (let key in voices.item) {
      const mat = voices.item[key]
      await this.createMaterial(mat, 'voice')
    }

    for (let key in news.item) {
      const mat = news.item[key]
      await this.createMaterial(mat, 'news')
    }

    return {
      images,
      videos,
      voices,
      news
    }
  }
}
